﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;

namespace common {
	public static class string_op {

		public static string numbertostring(decimal num) {
			var str1 = "零一二三四五六七八九";            //0-9所对应的汉字
			var str2 = "万千百十亿千百十万千百十元角分"; //数字位所对应的汉字
			var str3 = "";    //从原num值中取出的值
			var str4 = "";    //数字的字符串形式
			var str5 = "";  //人民币大写金额形式
			int i;    //循环变量
			int j;    //num的值乘以100的字符串长度
			var ch1 = "";    //数字的汉语读法
			var ch2 = "";    //数字位的汉字读法
			var nzero = 0;  //用来计算连续的零值是几个
			int temp;            //从原num值中取出的值

			num = Math.Round(Math.Abs(num));    //将num取绝对值并四舍五入取2位小数
			str4 = ((long)(num * 100)).ToString();        //将num乘100并转换成字符串形式
			j = str4.Length;      //找出最高位
			if (j > 15) { return "溢出"; }
			str2 = str2.Substring(15 - j);   //取出对应位数的str2的值。如：200.55,j为5所以str2=佰拾元角分

			//循环取出每一位需要转换的值
			for (i = 0; i < j; i++) {
				str3 = str4.Substring(i, 1);          //取出需转换的某一位的值
				temp = Convert.ToInt32(str3);      //转换为数字
				if (i != (j - 3) && i != (j - 7) && i != (j - 11) && i != (j - 15)) {
					//当所取位数不为元、万、亿、万亿上的数字时
					if (str3 == "0") {
						ch1 = "";
						ch2 = "";
						nzero = nzero + 1;
					} else {
						if (str3 != "0" && nzero != 0) {
							ch1 = "零" + str1.Substring(temp * 1, 1);
							ch2 = str2.Substring(i, 1);
							nzero = 0;
						} else {
							ch1 = str1.Substring(temp * 1, 1);
							ch2 = str2.Substring(i, 1);
							nzero = 0;
						}
					}
				} else {
					//该位是万亿，亿，万，元位等关键位
					if (str3 != "0" && nzero != 0) {
						ch1 = "零" + str1.Substring(temp * 1, 1);
						ch2 = str2.Substring(i, 1);
						nzero = 0;
					} else {
						if (str3 != "0" && nzero == 0) {
							ch1 = str1.Substring(temp * 1, 1);
							ch2 = str2.Substring(i, 1);
							nzero = 0;
						} else {
							if (str3 == "0" && nzero >= 3) {
								ch1 = "";
								ch2 = "";
								nzero = nzero + 1;
							} else {
								if (j >= 11) {
									ch1 = "";
									nzero = nzero + 1;
								} else {
									ch1 = "";
									ch2 = str2.Substring(i, 1);
									nzero = nzero + 1;
								}
							}
						}
					}
				}
				if (i == (j - 11) || i == (j - 3)) {
					//如果该位是亿位或元位，则必须写上
					ch2 = str2.Substring(i, 1);
				}
				str5 = str5 + ch1 + ch2;

				if (i == j - 1 && str3 == "0") {
					//最后一位（分）为0时，加上“整”
					//str5 = str5;
				}
			}
			if (num == 0) {
				str5 = "零元";
			}
			if (str5.StartsWith("二千") || str5.StartsWith("二万")) {
				str5 = "两" + str5.Substring(1);
			}
			if (str5.Contains("二分")) {
				str5 = str5.Replace("二分", "两分");
			}
			str5 = str5.Replace("零一十", "零十");
			return str5;
		}

		public static string datetostring(string strDate) {
			var strChinese = new char[] {
				 '零','一','二','三','四','五','六','七','八','九','十' };
			var result = new StringBuilder();

			//// 依据正则表达式判断参数是否正确
			//Regex theReg = new Regex(@"(d{2}|d{4})(/|-)(d{1,2})(/|-)(d{1,2})");

			if (!string.IsNullOrEmpty(strDate)) {
				// 将数字日期的年月日存到字符数组str中
				string[] str = null;
				if (strDate.Contains("-")) {
					str = strDate.Split('-');
				} else if (strDate.Contains("/")) {
					str = strDate.Split('/');
				}
				// str[0]中为年，将其各个字符转换为相应的汉字
				for (var i = 0; i < str[0].Length; i++) {
					result.Append(strChinese[int.Parse(str[0][i].ToString())]);
				}
				result.Append("年");

				// 转换月
				var month = int.Parse(str[1]);
				var MN1 = month / 10;
				var MN2 = month % 10;

				if (MN1 > 1) {
					result.Append(strChinese[MN1]);
				}
				if (MN1 > 0) {
					result.Append(strChinese[10]);
				}
				if (MN2 != 0) {
					result.Append(strChinese[MN2]);
				}
				result.Append("月");

				// 转换日
				var day = int.Parse(str[2]);
				var DN1 = day / 10;
				var DN2 = day % 10;

				if (DN1 > 1) {
					result.Append(strChinese[DN1]);
				}
				if (DN1 > 0) {
					result.Append(strChinese[10]);
				}
				if (DN2 != 0) {
					result.Append(strChinese[DN2]);
				}
				result.Append("日");
			} else {
				throw new ArgumentException();
			}

			return result.ToString();
		}


		public static bool isNumberic(string message, out int result) {
			var rex = new System.Text.RegularExpressions.Regex(@"^\d+$");
			result = -1;
			if (rex.IsMatch(message)) {
				result = int.Parse(message);
				return true;
			} else
				return false;
		}


		public static byte[] StructToBytes(object structure) {
			var num = Marshal.SizeOf(structure);
			var intPtr = Marshal.AllocHGlobal(num);
			byte[] result;
			try {
				Marshal.StructureToPtr(structure, intPtr, false);
				var array = new byte[num];
				Marshal.Copy(intPtr, array, 0, num);
				result = array;
			} finally {
				Marshal.FreeHGlobal(intPtr);
			}
			return result;
		}

		public static byte[] file_to_bytes(string filestr) {
			if (string.IsNullOrEmpty(filestr))
				throw new ArgumentNullException("audio_file is null", filestr);

			if (!File.Exists(filestr))
				throw new FileNotFoundException("audio_file is not exist", filestr);

			try {

				using (var fs = File.OpenRead(filestr)) {
					var data = new byte[fs.Length];
					fs.Read(data, 0, data.Length);

					return data;
				}
			} catch (Exception ex) {
				throw ex;
			}
		}

		public static string Ptr2Str(IntPtr p) {
			var lb = new List<byte>();
			while (Marshal.ReadByte(p) != 0) {
				lb.Add(Marshal.ReadByte(p));
				p = p + 1;
			}
			var bs = lb.ToArray();
			return Encoding.Default.GetString(lb.ToArray());
		}

		public static long Get1970ToNowSeconds() {
			return (DateTime.UtcNow.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
		}


		public static string GetMd5Hash(string input) {
			if (input == null) {
				return null;
			}

			var md5Hash = MD5.Create();

			// 将输入字符串转换为字节数组并计算哈希数据  
			var data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));

			// 创建一个 Stringbuilder 来收集字节并创建字符串  
			var sBuilder = new StringBuilder();

			// 循环遍历哈希数据的每一个字节并格式化为十六进制字符串  
			for (var i = 0; i < data.Length; i++) {
				sBuilder.Append(data[i].ToString("x2"));
			}

			// 返回十六进制字符串  
			return sBuilder.ToString();
		}

		public static int get_wav_length(List<string> file_list) {
			var len = 0;
			foreach (var file in file_list) {
				if (file.StartsWith("http")) {
					len += (int)(GetHttpLength(file) * 8 / 128000);
				} else {
					if (!File.Exists(file))
						continue;
					var fi = new FileInfo(file);
					len += (int)(fi.Length * 8 / 128000);
				}
			}
			return len == 0 ? 1 : len;

		}

		private static long GetHttpLength(string url) {
			var length = 0L;
			try {
				var req = (HttpWebRequest)WebRequest.CreateDefault(new Uri(url));
				req.Method = "HEAD";
				req.Timeout = 5000;
				var res = (HttpWebResponse)req.GetResponse();
				if (res.StatusCode == HttpStatusCode.OK) {
					length = res.ContentLength;
				}

				res.Close();
				return length;
			} catch (WebException) {
				return 0;
			}
		}




		public static string get_file_str(string file) {
			var file_info = "";
			try {
				if (!File.Exists(file))
					throw new FileNotFoundException("file not found", file);

				using (var fs = new FileStream(file, FileMode.Open)) {
					using (var sr = new StreamReader(fs)) {
						file_info = sr.ReadToEnd();
					}
				}
			} catch {

			}
			return file_info;
		}

		public static string format_string(string str, int fmt) {
			if (str.Length == fmt)
				return str;
			if (str.Length < fmt)
				return str.PadRight(fmt, ' ');
			else
				return (str.Substring(0, fmt - 3) + "...");
		}

		/// <summary>
		/// the same as  <seealso cref="string.IsNullOrEmpty(string)"/>
		/// </summary>
		/// <param name="str"></param>
		/// <returns></returns>
		public static bool IsEmpty(this string str) {
			return string.IsNullOrEmpty(str);
		}

		public static string ToSeriableString<T>(this List<T> _list) {
			var rest = "";
			if (_list.Count >= 0)
				foreach (var t in _list)
					rest += t.ToString() + ",";

			return rest.TrimEnd(',');
		}

		public static byte[] Toarray(this MemoryStream memory_stream) {
			var data = new byte[memory_stream.Length];
			memory_stream.Read(data, 0, data.Length);
			return data;
		}

		public static byte[] Merge(this byte[] dst_byte, byte[] src_byte) {
			var tmp = new byte[(dst_byte == null ? 0 : dst_byte.Length) + src_byte.Length];
			if (dst_byte != null)
				System.Buffer.BlockCopy(dst_byte, 0, tmp, 0, dst_byte.Length);

			System.Buffer.BlockCopy(src_byte, 0, tmp, dst_byte == null ? 0 : dst_byte.Length, src_byte.Length);
			return tmp;
		}

	}
}
